﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Bymed.SpineScan.Service;
using Bymed.SpineScan.Service.Interface;
using Bymed.SpineScan.Service.Shared;
using Bymed.SpineScan.WPF.Model;
using Bymed.SpineScan.WPF.Shared;
using Bymed.SpineScan.DataModel;

namespace Bymed.SpineScan.WPF.ViewModel
{
    public class PatientBasicInfoViewModel : PatientBasicInfoBaseViewModel
    {
        public const string GoToNextPageMessageToken = "PatientBasicInfoGoToNextPageMessage";
        public const string ChangeDataConfirmMessageToken = "PatientBasicInfoChangeDataConfirmMessage";
        private IPatientService _patientService;

        /// <summary>
        /// Initializes a new instance of the PatientBasicInfoViewModel class.
        /// </summary>
        public PatientBasicInfoViewModel(IDataService dataService)
            : base(dataService)
        {
            _patientService = ServiceFactory.CreatePatientService();

            try
            {
                GetPatientNumber();
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Get the next available patient number
        /// </summary>
        public void GetPatientNumber()
        {
            Number = _patientService.GetPatientNumber();
        }

        /// <summary>
        /// Reset the necessary properties for binding.
        /// </summary>
        public override void ResetProperties()
        {
            base.ResetProperties();

            Name = string.Empty;
            IsNewData = true;
            IsMale = true;
            IsFemale = false;
            Birthday = null;
            Height = string.Empty;
            Weight = string.Empty;
            Remark = string.Empty;

            GetPatientNumber();
        }

        private RelayCommand _nextCommand;

        /// <summary>
        /// Gets the NextCommand.
        /// </summary>
        public RelayCommand NextCommand
        {
            get
            {
                return _nextCommand ?? (_nextCommand = new RelayCommand(
                    ExecuteNextCommand,
                    CanExecuteNextCommand));
            }
        }

        private void ExecuteNextCommand()
        {
            try
            {
                // Adding new data
                if (IsNewData)
                {
                    // Check the existed data.
                    if (_patientService.Get(Number) == null)
                    {
                        AddNewPatient();
                        SendGotoNextPageMessage();
                    }
                    else
                    {
                        RequestDisplayMessage(string.Format("编号{0}已存在", Number));
                    }
                }
                else
                {
                    // Update existing data
                    UpdatePatient();
                    SendGotoNextPageMessage();
                }
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        private bool CanExecuteNextCommand()
        {
            if (string.IsNullOrEmpty(Number.Trim()) || 
                string.IsNullOrEmpty(Name.Trim()) || 
                !Birthday.HasValue)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        private RelayCommand _refreshCommand;

        /// <summary>
        /// Gets the RefreshCommand.
        /// </summary>
        public RelayCommand RefreshCommand
        {
            get
            {
                return _refreshCommand
                    ?? (_refreshCommand = new RelayCommand(
                                          () =>
                                          {
                                              ResetProperties();
                                          }));
            }
        }

        /// <summary>
        /// Assign the provided patient property value based on current ViewModel.
        /// </summary>
        /// <returns></returns>
        private void AssignPatientPropertyValue(Patient patient)
        {
            patient.Name = Name.Trim();
            patient.Number = Number.Trim();
            patient.Gender = (short)Gender;
            patient.Birthday = Birthday;
            patient.Height = Height.ConvertToNullable<short>();
            patient.Weight = Weight.ConvertToNullable<short>();
            patient.Remark = Remark.Trim();
            patient.UpdateOn = GeneralUtility.GetCurrentDateTime();
        }

        /// <summary>
        /// Add a new patient data into data source.
        /// </summary>
        private void AddNewPatient()
        {
            var patient = new Patient();
            AssignPatientPropertyValue(patient);
            patient.CreateOn = GeneralUtility.GetCurrentDateTime();
            _patientService.Add(patient);
            IsNewData = false;
        }

        /// <summary>
        /// Update the existing patient data.
        /// </summary>
        private void UpdatePatient()
        {
            var existedPatient = _patientService.Get(Number);

            if (existedPatient != null)
            {
                // Check if the data has been changed.
                if (existedPatient.Number != Number ||
                    existedPatient.Name != Name ||
                    existedPatient.Gender != (short)Gender ||
                    existedPatient.Birthday != Birthday ||
                    existedPatient.Height != Height.ConvertToNullable<short>() ||
                    existedPatient.Weight != Weight.ConvertToNullable<short>() ||
                    existedPatient.Remark != Remark)
                {
                    // Show a message to confirm whether user needs change the patient data.
                    var dialogMessage = new DialogMessage("确认更新数据？", dialogResult =>
                    {
                        // This is the CallBack of the DialogMessage.
                        if (dialogResult == MessageBoxResult.Yes)
                        {
                            try
                            {
                                AssignPatientPropertyValue(existedPatient);
                                _patientService.Update(existedPatient);
                            }
                            catch (Exception ex)
                            {
                                RequestDisplayErrorMessage(ex.Message);
                            }
                        }
                    })
                    {
                        Button = MessageBoxButton.YesNo,
                        Caption = "更新数据",
                        Icon = MessageBoxImage.Question
                    };

                    Messenger.Default.Send<DialogMessage>(dialogMessage, ChangeDataConfirmMessageToken);
                }
            }
        }

        /// <summary>
        /// Send GoToNextPageMessage to PatientBasicInfoPage.
        /// </summary>
        private void SendGotoNextPageMessage()
        {
            var patientBasicInfoDisplayViewModel = new PatientBasicInfoDisplayViewModel(null)
            {
                Number = Number,
                Name = Name,
                IsMale = IsMale,
                IsFemale = IsFemale,
                Birthday = Birthday,
                Remark = Remark,
                GenderDisplay = IsMale ? "男" : "女",
                BirthdayDisplay = GeneralUtility.DisplayBirthday(Birthday)
            };

            // Send GoToNextPageMessage to PatientBasicInfoPage.
            Messenger.Default.Send<PatientBasicInfoDisplayViewModel>(patientBasicInfoDisplayViewModel, GoToNextPageMessageToken);
        }
    }
}
